package com.git.groovy.service;

import com.git.groovy.config.ProjectConfig;
import com.git.groovy.utils.GroovyUtil;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.transport.*;
import org.eclipse.jgit.util.FS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class GroovyScriptService {

    @Autowired
    public ProjectConfig projectConfig;

    /**
     * 存对象地址
     */
    private Map<String, Object> cacheObject = new ConcurrentHashMap<>();

    public synchronized boolean updateScript(){
        UsernamePasswordCredentialsProvider credentials = new UsernamePasswordCredentialsProvider("username", "password");
        String localPath = projectConfig.getGroovyScriptLocalPath();
        String branch = projectConfig.getEvn();
        File repoDir = new File(localPath);
        if (!repoDir.exists()) {
            repoDir.mkdirs();
        }
        File repoGitDir = new File(repoDir.getAbsolutePath() + "/.git");
        try {
            if(!repoGitDir.exists()){
                //git clone
                log.info("load type: clone");
                Git.cloneRepository().setURI(projectConfig.getGitUrl())
                        .setBranch(branch)
                        .setDirectory(repoDir)
    //                    .setCredentialsProvider(credentials) //设置权限验证
                        .call();
            }else{
                //git pull
                log.info("load type: pull");
                //                new Git(new FileRepository(repoDir.getAbsolutePath())).pull().setRemoteBranchName(branch).setCredentialsProvider(credentials).call();
                new Git(new FileRepository(repoDir.getAbsolutePath())).pull().setRemoteBranchName(branch).call();
            }
        } catch (GitAPIException | IOException e) {
            log.error("error:{}",e);
            return false;
        }
        //清空缓存
        cacheObject.clear();
        return true;
    }

    /**
     * @Author Alan liu
     * @Description 从缓存中取执行对象，后要改进只更新一个文件路径
     * @param filePath
     **/
    public  <T> T getGroovyScriptEngine(String filePath) throws IllegalAccessException, IOException, InstantiationException {
        T object = (T) cacheObject.get(filePath);
        if(object == null){
            synchronized (this){
                T obj = GroovyUtil.loaderClass(projectConfig.getGroovyScriptLocalPath() + filePath);
                if(obj != null){
                    cacheObject.put(filePath,obj);
                }
                return obj;
            }
        }else {
            return object;
        }
    }

    public static void main(String[] args) {
        final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
            /**
             *  解除HostKey检查，也就意味着可以接受未知的远程主机的文件，这是不安全的，这种模式只是用于测试为目的的。
             *  利用ssh-keyscan -t rsa hostname，收集主机数据。
             * @param host
             * @param session
             */
            @Override
            protected void configure(OpenSshConfig.Host host, Session session) {
                session.setConfig("StrictHostKeyChecking", "no");
            }

            @Override
            protected JSch createDefaultJSch(FS fs) throws JSchException {
                JSch jSch = super.createDefaultJSch(fs);
                jSch.addIdentity("C:/Users/xxx/.ssh/id_rsa_git");
                jSch.setKnownHosts("C:/Users/xxx/.ssh/known_hosts");
                return jSch;
            }
        };
        CloneCommand cloneCommand = Git.cloneRepository();
        cloneCommand.setTransportConfigCallback(new TransportConfigCallback() {
            @Override
            public void configure(Transport transport) {
                SshTransport sshTransport = (SshTransport) transport;
                sshTransport.setSshSessionFactory(sshSessionFactory);
            }
        });
        cloneCommand.setURI("git@github.com:xxx/xxx.git");
        cloneCommand.setDirectory(new File("C:/Users/xxx/Documents/code/testtest"));
        try {
            cloneCommand.call().checkout();
        } catch (GitAPIException e) {
            e.printStackTrace();
        }
    }

}
